package com.cskaoyan.javase.oop1._13block._2building;
/**
 * 构造代码块
 * 语法:{}
 * 定义位置: 类体中的成员位置,和构造器一样
 * 作用: 随着构造器的执行而执行,用来在创建对象过程中,给成员变量赋值
 * 总结一下,在创建对象过程中,给成员变量赋值的方式:
 *      1.默认初始化,具有默认值
 *      2.显式赋值
 *      3.构造器
 *      4.构造代码块
 * 以上赋值方式,遵循"掐头去尾"的原则,默认初始化是永远的第一步,构造器永远最后一步执行
 * 通过测试,我们发现显式赋值和构造代码块赋值顺序是:
 *      按照代码的书写顺序,从上到下执行
 *
 * 原理:
 * 研究构造代码块赋值和显式赋值,为什么会按照代码书写顺序从上到下执行.
 * 编译后的代码中并不存在构造代码块的结构,编译器会智能地将构造代码块中的赋值语句和显式赋值语句,放入类中所有构造器的前几行语句.
 * 何为智能?
 *      为了保证显式赋值和构造代码块赋值按照代码书写顺序从上到下执行.
 *      当然还会保证,它们都会在构造器赋值之前进行
 *
 * 于是，我们可以得出以下结论：
 * 使用new对象的方式创建对象，不论使用哪个构造器，构造代码块都会随之执行
 * 构造器是每一次new对象都会执行一次，所以构造代码块也会随之执行一次
 * 构造代码块中的代码要放入构造器的首几行，所以在同一个类中：
 * 构造代码块总是先于它的构造器而执行
 *
 * 这里就可以总结一个构造代码块的用途:
 *    假如new对象,无论哪个构造器都需要执行一段代码
 *    这段代码可以"提取公因式"
 *    放到构造代码块中
 *
 *
 * @since 10:14
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student(29);
        System.out.println(s.age);
        System.out.println("---------------");
        Student s2 = new Student();
        System.out.println(s2.age);
    }
}
class Student{

    // 构造代码块
    {
        age = 18;
        System.out.println("Student building block");
    }
    int age = 10;

    public Student() {
    }

    public Student(int age) {
        this.age = age;
    }
}
